package com.fr.base.core.image4j.codec.bmp;

import com.fr.base.core.image4j.io.LittleEndianOutputStream;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class BMPEncoder
{
  public static void write(BufferedImage paramBufferedImage, File paramFile)
    throws IOException
  {
    write(paramBufferedImage, new FileOutputStream(paramFile));
  }

  public static void write(BufferedImage paramBufferedImage, OutputStream paramOutputStream)
    throws IOException
  {
    InfoHeader localInfoHeader = createInfoHeader(paramBufferedImage);
    int i = 0;
    IndexColorModel localIndexColorModel = null;
    if (localInfoHeader.sBitCount <= 8)
    {
      localIndexColorModel = (IndexColorModel)paramBufferedImage.getColorModel();
      i = localIndexColorModel.getMapSize();
    }
    int j = 14 + localInfoHeader.iSize;
    int k = 4 * i;
    int l = j + k;
    int i1 = 0;
    switch (localInfoHeader.sBitCount)
    {
    case 1:
      i1 = getBytesPerLine1(localInfoHeader.iWidth);
      break;
    case 4:
      i1 = getBytesPerLine4(localInfoHeader.iWidth);
      break;
    case 8:
      i1 = getBytesPerLine8(localInfoHeader.iWidth);
      break;
    case 24:
      i1 = getBytesPerLine24(localInfoHeader.iWidth);
      break;
    case 32:
      i1 = localInfoHeader.iWidth * 4;
    }
    int i2 = l + i1 * localInfoHeader.iHeight;
    LittleEndianOutputStream localLittleEndianOutputStream = new LittleEndianOutputStream(paramOutputStream);
    writeFileHeader(i2, l, localLittleEndianOutputStream);
    localInfoHeader.write(localLittleEndianOutputStream);
    if (localInfoHeader.sBitCount <= 8)
      writeColorMap(localIndexColorModel, localLittleEndianOutputStream);
    switch (localInfoHeader.sBitCount)
    {
    case 1:
      write1(paramBufferedImage.getRaster(), localLittleEndianOutputStream);
      break;
    case 4:
      write4(paramBufferedImage.getRaster(), localLittleEndianOutputStream);
      break;
    case 8:
      write8(paramBufferedImage.getRaster(), localLittleEndianOutputStream);
      break;
    case 24:
      write24(paramBufferedImage.getRaster(), localLittleEndianOutputStream);
      break;
    case 32:
      write32(paramBufferedImage.getRaster(), paramBufferedImage.getAlphaRaster(), localLittleEndianOutputStream);
    }
  }

  public static InfoHeader createInfoHeader(BufferedImage paramBufferedImage)
  {
    InfoHeader localInfoHeader = new InfoHeader();
    localInfoHeader.iColorsImportant = 0;
    localInfoHeader.iColorsUsed = 0;
    localInfoHeader.iCompression = 0;
    localInfoHeader.iHeight = paramBufferedImage.getHeight();
    localInfoHeader.iWidth = paramBufferedImage.getWidth();
    localInfoHeader.sBitCount = (short)paramBufferedImage.getColorModel().getPixelSize();
    localInfoHeader.iNumColors = (1 << ((localInfoHeader.sBitCount == 32) ? 24 : localInfoHeader.sBitCount));
    localInfoHeader.iImageSize = 0;
    return localInfoHeader;
  }

  public static void writeFileHeader(int paramInt1, int paramInt2, LittleEndianOutputStream paramLittleEndianOutputStream)
    throws IOException
  {
    byte[] arrayOfByte = "BM".getBytes("UTF-8");
    paramLittleEndianOutputStream.write(arrayOfByte);
    paramLittleEndianOutputStream.writeIntLE(paramInt1);
    paramLittleEndianOutputStream.writeIntLE(0);
    paramLittleEndianOutputStream.writeIntLE(paramInt2);
  }

  public static void writeColorMap(IndexColorModel paramIndexColorModel, LittleEndianOutputStream paramLittleEndianOutputStream)
    throws IOException
  {
    int i = paramIndexColorModel.getMapSize();
    for (int j = 0; j < i; ++j)
    {
      int k = paramIndexColorModel.getRGB(j);
      int l = k >> 16 & 0xFF;
      int i1 = k >> 8 & 0xFF;
      int i2 = k & 0xFF;
      paramLittleEndianOutputStream.writeByte(i2);
      paramLittleEndianOutputStream.writeByte(i1);
      paramLittleEndianOutputStream.writeByte(l);
      paramLittleEndianOutputStream.writeByte(0);
    }
  }

  public static int getBytesPerLine1(int paramInt)
  {
    int i = paramInt / 8;
    if (i % 4 != 0)
      i = (i / 4 + 1) * 4;
    return i;
  }

  public static int getBytesPerLine4(int paramInt)
  {
    int i = paramInt / 2;
    if (i % 4 != 0)
      i = (i / 4 + 1) * 4;
    return i;
  }

  public static int getBytesPerLine8(int paramInt)
  {
    int i = paramInt;
    if (i % 4 != 0)
      i = (i / 4 + 1) * 4;
    return i;
  }

  public static int getBytesPerLine24(int paramInt)
  {
    int i = paramInt * 3;
    if (i % 4 != 0)
      i = (i / 4 + 1) * 4;
    return i;
  }

  public static int getBitmapSize(int paramInt1, int paramInt2, int paramInt3)
  {
    int i = 0;
    switch (paramInt3)
    {
    case 1:
      i = getBytesPerLine1(paramInt1);
      break;
    case 4:
      i = getBytesPerLine4(paramInt1);
      break;
    case 8:
      i = getBytesPerLine8(paramInt1);
      break;
    case 24:
      i = getBytesPerLine24(paramInt1);
      break;
    case 32:
      i = paramInt1 * 4;
    }
    int j = i * paramInt2;
    return j;
  }

  public static void write1(Raster paramRaster, LittleEndianOutputStream paramLittleEndianOutputStream)
    throws IOException
  {
    int i = getBytesPerLine1(paramRaster.getWidth());
    byte[] arrayOfByte = new byte[i];
    for (int j = paramRaster.getHeight() - 1; j >= 0; --j)
    {
      for (int k = 0; k < i; ++k)
        arrayOfByte[k] = 0;
      for (k = 0; k < paramRaster.getWidth(); ++k)
      {
        int l = k / 8;
        int i1 = k % 8;
        int i2 = paramRaster.getSample(k, j, 0);
        arrayOfByte[l] = setBit(arrayOfByte[l], i1, i2);
      }
      paramLittleEndianOutputStream.write(arrayOfByte);
    }
  }

  public static void write4(Raster paramRaster, LittleEndianOutputStream paramLittleEndianOutputStream)
    throws IOException
  {
    int i = paramRaster.getWidth();
    int j = paramRaster.getHeight();
    int k = getBytesPerLine4(i);
    byte[] arrayOfByte = new byte[k];
    for (int l = j - 1; l >= 0; --l)
    {
      for (int i1 = 0; i1 < k; ++i1)
        arrayOfByte[i1] = 0;
      for (i1 = 0; i1 < i; ++i1)
      {
        int i2 = i1 / 2;
        int i3 = i1 % 2;
        int i4 = paramRaster.getSample(i1, l, 0);
        arrayOfByte[i2] = setNibble(arrayOfByte[i2], i3, i4);
      }
      paramLittleEndianOutputStream.write(arrayOfByte);
    }
  }

  public static void write8(Raster paramRaster, LittleEndianOutputStream paramLittleEndianOutputStream)
    throws IOException
  {
    int i = paramRaster.getWidth();
    int j = paramRaster.getHeight();
    int k = getBytesPerLine8(i);
    for (int l = j - 1; l >= 0; --l)
    {
      for (int i1 = 0; i1 < i; ++i1)
      {
        int i2 = paramRaster.getSample(i1, l, 0);
        paramLittleEndianOutputStream.writeByte(i2);
      }
      for (i1 = i; i1 < k; ++i1)
        paramLittleEndianOutputStream.writeByte(0);
    }
  }

  public static void write24(Raster paramRaster, LittleEndianOutputStream paramLittleEndianOutputStream)
    throws IOException
  {
    int i = paramRaster.getWidth();
    int j = paramRaster.getHeight();
    int k = getBytesPerLine24(i);
    for (int l = j - 1; l >= 0; --l)
    {
      for (int i1 = 0; i1 < i; ++i1)
      {
        int i2 = paramRaster.getSample(i1, l, 0);
        int i3 = paramRaster.getSample(i1, l, 1);
        int i4 = paramRaster.getSample(i1, l, 2);
        paramLittleEndianOutputStream.writeByte(i4);
        paramLittleEndianOutputStream.writeByte(i3);
        paramLittleEndianOutputStream.writeByte(i2);
      }
      for (i1 = i * 3; i1 < k; ++i1)
        paramLittleEndianOutputStream.writeByte(0);
    }
  }

  public static void write32(Raster paramRaster1, Raster paramRaster2, LittleEndianOutputStream paramLittleEndianOutputStream)
    throws IOException
  {
    int i = paramRaster1.getWidth();
    int j = paramRaster1.getHeight();
    for (int k = j - 1; k >= 0; --k)
      for (int l = 0; l < i; ++l)
      {
        int i1 = paramRaster1.getSample(l, k, 0);
        int i2 = paramRaster1.getSample(l, k, 1);
        int i3 = paramRaster1.getSample(l, k, 2);
        int i4 = paramRaster2.getSample(l, k, 0);
        paramLittleEndianOutputStream.writeByte(i3);
        paramLittleEndianOutputStream.writeByte(i2);
        paramLittleEndianOutputStream.writeByte(i1);
        paramLittleEndianOutputStream.writeByte(i4);
      }
  }

  private static byte setBit(byte paramByte, int paramInt1, int paramInt2)
  {
    if (paramInt2 == 0)
      paramByte = (byte)(paramByte & (1 << 7 - paramInt1 ^ 0xFFFFFFFF));
    else
      paramByte = (byte)(paramByte | 1 << 7 - paramInt1);
    return paramByte;
  }

  private static byte setNibble(byte paramByte, int paramInt1, int paramInt2)
  {
    paramByte = (byte)(paramByte | paramInt2 << (1 - paramInt1) * 4);
    return paramByte;
  }

  public static int getColorMapSize(short paramShort)
  {
    int i = 0;
    if (paramShort <= 8)
      i = (1 << paramShort) * 4;
    return i;
  }
}